﻿using MyHelper;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace weighing
{
    /// <summary>
    /// ### ActiveCode

    /// JLASD-DFADG-LADID-2513W-5684G

    ///1. 软件版本
    ///   1. 头两个字字母 BN，结尾的两个字母 HQ
    ///   2. 第一段的第三个字母是软件版本控制 字母
    ///      1. B 基础版本
    ///      2. H 高级版本(实现无人值守)
    ///   3. 第二段，第一个字必须 为（G或者N）是否是通用型（G不需要提前生成密钥）
    ///   4. 第二段，第二个字必须 为（H或者B）是否是通用型（H针对高线版本，B基础版本）
    ///   5. 第二段第三个数字控制 是否为永久激活版本
    ///   6. 第三段，第一个字必须 为（L或者O）L 本地激活 O在线激活
    ///   7. 第三，四，五 段 的3, 4两个数字 拼接后，控制激活时长`天数`
    //    8. 其余的随机
    /// </summary>
    public class ActiveCodeHelper
    {
        #region variables
        private static Random random;
        private static readonly object syncObj = new object();
        #endregion

        /// <summary>
        /// 生成激活码
        /// </summary>
        /// <param name="versionType">版本</param>
        /// <param name="isNever">是否永久</param>
        /// <param name="year">激活年数</param>
        /// <returns></returns>
        public static string GeneraterCode(bool isNever = false, int year = 1)
        {
            string header = "BN", end = "HQ", splitChar = "-", v = "B", never = "F";

            if (isNever) never = "T";

            string one = header + v + RandomChart(2);
            string two = RandomChart(2) + never + RandomChart(2);
            string three, four, fire;
            if (isNever)
            {
                three = "L" + RandomChart(1) + 99 + RandomChart(1);
                four = RandomChart(2) + 99 + RandomChart(1);
                fire = RandomChart(1) + 99 + end;
            }
            else if (year == 1 || year < 1 || year > 100)
            {
                three = "L" + RandomChart(1) + "00" + RandomChart(1);
                four = RandomChart(2) + "03" + RandomChart(1);
                fire = RandomChart(1) + "65" + end;
            }
            else
            {
                int days = year * 365;
                string temp = days.ToString();

                int dif = 6 - temp.Length;
                for (int i = 0; i < dif; i++)
                {
                    temp = "0" + temp;
                }

                three = "L" + RandomChart(1) + temp.Substring(0, 2) + RandomChart(1);
                four = RandomChart(2) + temp.Substring(2, 2) + RandomChart(1);
                fire = RandomChart(1) + temp.Substring(4, 2) + end;
            }
            return one + splitChar + two + splitChar + three + splitChar + four + splitChar + fire;
        }


        private static string RandomChart(int len)
        {
            string chats = "ABCDEFGHIJ567KLMNPQWXY1234890";
            string res = "";
            lock (syncObj)
            {
                random ??= new Random();
                for (int i = 0; i < len; i++)
                {
                    int v = random.Next(chats.Length);
                    res += chats[v];
                }
                return res;
            }

        }

        /// <summary>
        /// 分析 激活码 是否合法
        /// </summary>
        /// <param name="code"></param>
        /// <returns></returns>
        public static bool AnalysisCode(String code)
        {
            if (code == null || code.Length != 29 || !code.StartsWith("BN") || !code.EndsWith("HQ"))
            {
                return false;
            }
            string v = code.Substring(2, 1);
            if (v != "B" && v != "H")
            {
                return false;
            }
            string isNerver = code.Substring(8, 1);
            if (isNerver != "T" && isNerver != "F")
            {
                return false;
            }

            string local = code.Substring(12, 1);
            if (local != "O" && local != "L")
            {
                return false;
            }
            string[] temps = code.Split('-');
            string y = temps[2].Substring(2, 2) + temps[3].Substring(2, 2) + temps[4].Substring(1, 2);
            int year = 0;
            try
            {
                year = Convert.ToInt32(y) / 365;
            }
            catch (Exception e)
            {
                Console.WriteLine(e.Message);
            }
            if (year == 0)
            {
                return false;
            }
            return true;
        }


        /// <summary>
        /// 生成 通用 激活码 不需要提前生成密钥文件
        /// </summary>   
        /// <param name="isNever">是否永久</param>
        /// <param name="year">激活年数</param>
        /// <returns></returns>
        public static string GeneraterGernalCode(bool isNever = false, int year = 1)
        {
            string header = "BN", end = "HQ", splitChar = "-", v = "B", never = "F";
            string gernal = "G";
            if (isNever) never = "T";

            string one = header + v + RandomChart(2);
            string two = gernal + v + never + RandomChart(2);
            string three, four, fire;
            if (isNever)
            {
                three = "L" + RandomChart(1) + 99 + RandomChart(1);
                four = RandomChart(2) + 99 + RandomChart(1);
                fire = RandomChart(1) + 99 + end;
            }
            else if (year == 1 || year < 1 || year > 100)
            {
                three = "L" + RandomChart(1) + "00" + RandomChart(1);
                four = RandomChart(2) + "03" + RandomChart(1);
                fire = RandomChart(1) + "65" + end;
            }
            else
            {
                int days = year * 365;
                string temp = days.ToString();

                int dif = 6 - temp.Length;
                for (int i = 0; i < dif; i++)
                {
                    temp = "0" + temp;
                }

                three = "L" + RandomChart(1) + temp.Substring(0, 2) + RandomChart(1);
                four = RandomChart(2) + temp.Substring(2, 2) + RandomChart(1);
                fire = RandomChart(1) + temp.Substring(4, 2) + end;
            }
            return one + splitChar + two + splitChar + three + splitChar + four + splitChar + fire;
        }

        /// <summary>
        /// 分析 通用激活码 是否合法
        /// </summary>
        /// <param name="code"></param>
        /// <returns></returns>
        public static bool AnalysisGernalCode(String code)
        {
            if (code == null || code.Length != 29 || !code.StartsWith("BN") || !code.EndsWith("HQ"))
            {
                return false;
            }
            string v = code.Substring(2, 1);
            if (v != "B" && v != "H")
            {
                return false;
            }
            string isNerver = code.Substring(8, 1);
            if (isNerver != "T" && isNerver != "F")
            {
                return false;
            }
            string local = code.Substring(12, 1);
            if (local != "O" && local != "L")
            {
                return false;
            }
            string[] temps = code.Split('-');
            string y = temps[2].Substring(2, 2) + temps[3].Substring(2, 2) + temps[4].Substring(1, 2);
            int year = 0;
            try
            {
                year = Convert.ToInt32(y) / 365;
            }
            catch (Exception e)
            {
                Console.WriteLine(e.Message);
            }
            if (year == 0)
            {
                return false;
            }
            return true;

        }

        /// <summary>
        /// 是否是通用 激活码 
        /// </summary>
        /// <param name="code">激活码 </param>
        /// <returns></returns>
        public static bool IsGernalCode(string code)
        {
            if (code == null || code.Length != 29 || !code.StartsWith("BN") || !code.EndsWith("HQ"))
            {
                return false;
            }
            string v = code.Substring(2, 1);
            if (v != "B" && v != "H")
            {
                return false;
            }

            string g = code.Substring(6, 1);
            if (g != "G")
            {
                return false;
            }
            return true;
        }

        /// <summary>
        /// 是否是永久 激活码 
        /// </summary>
        /// <param name="code">激活码 </param>
        /// <returns></returns>
        public static bool IsNeverCode(string code)
        {
            bool res;
            res = AnalysisCode(code);
            if (res == false) res = AnalysisGernalCode(code);
            if (res == false) return false;
            string isNerver = code.Substring(8, 1);
            res = isNerver == "T";
            return res;
        }

        /// <summary>
        /// 软件是激活
        /// </summary>
        /// <returns></returns>
        public static bool IsSoftActive()
        {
            if (App.Config == null) return false;
            string code = App.Config.ActiveCode;
            if (string.IsNullOrEmpty(code) || App.Config.ActiveTime == null || App.Config.RadomKey.IsNullOrEmpty()) return false;
            string radomKey = EncryptHelper.Encrypto(code.Substring(0, 20));
            if (App.Config.RadomKey != radomKey) return false;
            bool isGernal = ActiveCodeHelper.IsGernalCode(code);
            if (isGernal)
            {
                return AnalysisGernalCode(code);
            }

            if (!AnalysisCode(code))
            {
                return false;
            }
            string nfn = Constant.ActiveCodeEncryptFile;
            if (!FileHelper.Exists(nfn))
            {
                return false;
            }
            List<string> lines = FileHelper.ReadFileLines(nfn, Encoding.UTF8);
            //有值比较随机码
            if (lines.Count > 0 && App.Config.RadomKey == lines[0])
            {
                return true;
            }
            return false;
        }

        /// <summary>
        /// 有效期
        /// </summary>
        /// <returns></returns>
        public static string GetEffictiveTime(string code)
        {
            if (string.IsNullOrEmpty(code))
            {
                return "未知";
            }
            if (IsNeverCode(code))
            {
                return "永久使用";
            }
            if (App.Config.ActiveTime != null)
            {
                var date = App.Config.ActiveTime?.AddYears(GetYears(App.Config.ActiveCode));
                return "有效期:" + date?.ToString("yyyy-MM-dd 23:59:59");
            }
            return "未知";
        }
        public static int GetYears(String code)
        {
            string[] temps = code.Split('-');
            string y = temps[2].Substring(2, 2) + temps[3].Substring(2, 2) + temps[4].Substring(1, 2);
            int year = Convert.ToInt32(y) / 365;
            return year;
        }
    }
}